{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e770779b",
   "metadata": {},
   "source": [
    "# 模型检测\n",
    "使用刚刚训练好的模型来进行检测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "21e3319c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]\n"
     ]
    }
   ],
   "source": [
    "# 设置使用GPU运行\n",
    "import tensorflow as tf\n",
    "\n",
    "gpus = tf.config.list_physical_devices(\"GPU\")\n",
    "\n",
    "if gpus:\n",
    "    tf.config.experimental.set_memory_growth(gpus[0], True)  #设置GPU显存用量按需使用\n",
    "    tf.config.set_visible_devices([gpus[0]],\"GPU\")\n",
    "\n",
    "print(gpus)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b1e3cfc",
   "metadata": {},
   "source": [
    "此处同样使用tf.keras.preprocessing.image_dataset_from_directory从测试集导入数据，不需要进行进一步划分，在Train&Save.ipynb里的参数validation_split(验证集比例)、subset(数据集类型)和seed(随机划分种子)均不必再设置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c0fe685c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 3326 files belonging to 3 classes.\n",
      "['cloud', 'cloudy', 'sun']\n"
     ]
    }
   ],
   "source": [
    "img_height = 200\n",
    "img_width  = 150\n",
    "batch_size = 9\n",
    "\n",
    "\"\"\"\n",
    "设置测试集\n",
    "\"\"\"\n",
    "test_ds = tf.keras.preprocessing.image_dataset_from_directory(\n",
    "    \"./TestDataSet/\",\n",
    "    label_mode = \"categorical\",\n",
    "    image_size=(img_height, img_width),\n",
    "    batch_size=batch_size)\n",
    "class_names = test_ds.class_names\n",
    "print(class_names)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "75fecf4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入预先训练好的模型\n",
    "from  tensorflow.keras.models import load_model\n",
    "Des_classifier=load_model(\"my_model_DesNet.h5\")\n",
    "Res_classifier=load_model(\"my_model_ResNet.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a835557f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "已检测9.02 %的数据\n",
      "已检测18.04 %的数据\n",
      "已检测27.06 %的数据\n",
      "已检测36.08 %的数据\n",
      "已检测45.10 %的数据\n",
      "已检测54.12 %的数据\n",
      "已检测63.14 %的数据\n",
      "已检测72.16 %的数据\n",
      "已检测81.18 %的数据\n",
      "已检测90.20 %的数据\n",
      "已检测99.22 %的数据\n",
      "共 3326 张测试图，DenseNet正确识别 3292 张，RenseNet正确识别 3299 张\n",
      "DenseNet正确率: 98.98 %     RenseNet正确率:99.19 %\n"
     ]
    }
   ],
   "source": [
    "# 测试一下准确率\n",
    "from PIL import Image\n",
    "import os\n",
    "import numpy as np\n",
    "test_dir = \"./TestDataSet/\"\n",
    "test_dirs = os.listdir(test_dir)\n",
    "\n",
    "i,j,k = 0, 0, 0\n",
    "for images, labels in test_ds:\n",
    "    for img, label in zip(images, labels):\n",
    "        i = i+1\n",
    "        if i%300 == 0 :\n",
    "            print(\"已检测%.2f\"%(i/33.26),\"%的数据\")\n",
    "        image = tf.image.resize(img, [img_height, img_width])/255.0\n",
    "        # 测试前需要给图片增加一个维度\n",
    "        img_array = tf.expand_dims(image, 0) \n",
    "        \n",
    "        prediction1 = Des_classifier.predict(img_array)\n",
    "        prediction2 = Res_classifier.predict(img_array)\n",
    "        if class_names[np.argmax(prediction1)] == class_names[np.argmax(label)]:\n",
    "            j=j+1\n",
    "        if class_names[np.argmax(prediction2)] == class_names[np.argmax(label)]:\n",
    "            k=k+1\n",
    "\n",
    "print(\"共\",i,\"张测试图，DenseNet正确识别\",j,\"张，RenseNet正确识别\",k,\"张\")\n",
    "print(\"DenseNet正确率: %.2f\"%(j/i*100),\"%    \",\"RenseNet正确率:%.2f\"%(k/i*100),\"%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "13c928ce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x432 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "import seaborn as sns\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 定义一个绘制混淆矩阵图的函数\n",
    "def plot_cm(labels1, predictions1,labels2, predictions2):\n",
    "    \n",
    "    # 生成混淆矩阵\n",
    "    conf_numpy1 = confusion_matrix(labels1, predictions1)\n",
    "    conf_numpy2 = confusion_matrix(labels2, predictions2)\n",
    "    # 将矩阵转化为 DataFrame\n",
    "    conf_df1 = pd.DataFrame(conf_numpy1, index=class_names ,columns=class_names)  \n",
    "    conf_df2 = pd.DataFrame(conf_numpy2, index=class_names ,columns=class_names)  \n",
    "    \n",
    "    plt.figure(figsize=(15,6))\n",
    "    plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "    plt.subplot(1,2,1)\n",
    "    sns.heatmap(conf_df1, annot=True, fmt=\"d\", cmap=\"Blues\")\n",
    "    plt.suptitle('混淆矩阵')\n",
    "    \n",
    "    plt.title('DenseNet121',fontsize=15)\n",
    "    plt.ylabel('真实值',fontsize=14)\n",
    "    plt.xlabel(' 预测值',fontsize=14)\n",
    "    plt.subplot(1,2,2)\n",
    "    sns.heatmap(conf_df2, annot=True, fmt=\"d\", cmap=\"Blues\")\n",
    "    \n",
    "    plt.title('ResNet50',fontsize=15)\n",
    "    plt.ylabel('真实值',fontsize=14)\n",
    "    plt.xlabel('预测值',fontsize=14)\n",
    "\n",
    "val_pre1   = []\n",
    "val_label1 = []\n",
    "val_pre2   = []\n",
    "val_label2 = []\n",
    "\n",
    "for images, labels in test_ds:#这里可以取部分验证数据（.take(1)）生成混淆矩阵\n",
    "    for img, label in zip(images, labels):\n",
    "        image = tf.image.resize(img, [img_height, img_width])/255.0\n",
    "        # 测试前需要给图片增加一个维度\n",
    "        img_array = tf.expand_dims(image, 0) \n",
    "        \n",
    "        prediction1 = Des_classifier.predict(img_array)\n",
    "        prediction2 = Res_classifier.predict(img_array)\n",
    "\n",
    "        val_pre1.append(np.argmax(prediction1))\n",
    "        val_label1.append([np.argmax(one_hot)for one_hot in [label]])\n",
    "        val_pre2.append(np.argmax(prediction2))\n",
    "        val_label2.append([np.argmax(one_hot)for one_hot in [label]])\n",
    "plot_cm(val_label1, val_pre1,val_label2, val_pre2)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
